package com.eshunda.eshunda_android_demo.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * HTTP 工具类 - 基于 OkHttp 实现
 */
public class HttpUtils {
    
    private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    private static final int CONNECT_TIMEOUT = 30;
    private static final int READ_TIMEOUT = 30;
    private static final int WRITE_TIMEOUT = 30;
    
    private static OkHttpClient client;
    
    /**
     * 获取 OkHttpClient 实例（单例）
     */
    private static OkHttpClient getClient() {
        if (client == null) {
            synchronized (HttpUtils.class) {
                if (client == null) {
                    client = new OkHttpClient.Builder()
                            .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
                            .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
                            .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
                            .retryOnConnectionFailure(true)
                            .build();
                }
            }
        }
        return client;
    }
    
    /**
     * GET 请求
     */
    public static HttpResponse doGet(String host, String path, String method, 
                                     Map<String, String> headers, 
                                     Map<String, String> querys) throws Exception {
        String url = buildUrl(host, path, querys);
        Request.Builder builder = new Request.Builder().url(url);
        
        // 添加请求头
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        
        Request request = builder.build();
        return executeRequest(request);
    }
    
    /**
     * POST 请求 (application/x-www-form-urlencoded)
     */
    public static HttpResponse doPost(String host, String path, String method,
                                      Map<String, String> headers,
                                      Map<String, String> querys,
                                      Map<String, String> bodys) throws Exception {
        String url = buildUrl(host, path, querys);
        
        // 构建表单body
        FormBody.Builder formBuilder = new FormBody.Builder();
        if (bodys != null && !bodys.isEmpty()) {
            for (Map.Entry<String, String> entry : bodys.entrySet()) {
                formBuilder.add(entry.getKey(), entry.getValue());
            }
        }
        
        Request.Builder builder = new Request.Builder()
                .url(url)
                .post(formBuilder.build());
        
        // 添加请求头
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        
        Request request = builder.build();
        return executeRequest(request);
    }
    
    /**
     * POST 请求 (String body)
     */
    public static HttpResponse doPost(String host, String path, String method,
                                      Map<String, String> headers,
                                      Map<String, String> querys,
                                      String body) throws Exception {
        String url = buildUrl(host, path, querys);
        
        RequestBody requestBody = RequestBody.create(body, JSON);
        
        Request.Builder builder = new Request.Builder()
                .url(url)
                .post(requestBody);
        
        // 添加请求头
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        
        Request request = builder.build();
        return executeRequest(request);
    }
    
    /**
     * POST 请求 (byte[] body)
     */
    public static HttpResponse doPost(String host, String path, String method,
                                      Map<String, String> headers,
                                      Map<String, String> querys,
                                      byte[] body) throws Exception {
        String url = buildUrl(host, path, querys);
        
        RequestBody requestBody = RequestBody.create(body, JSON);
        
        Request.Builder builder = new Request.Builder()
                .url(url)
                .post(requestBody);
        
        // 添加请求头
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        
        Request request = builder.build();
        return executeRequest(request);
    }
    
    /**
     * PUT 请求 (String body)
     */
    public static HttpResponse doPut(String host, String path, String method,
                                     Map<String, String> headers,
                                     Map<String, String> querys,
                                     String body) throws Exception {
        String url = buildUrl(host, path, querys);
        
        RequestBody requestBody = RequestBody.create(body, JSON);
        
        Request.Builder builder = new Request.Builder()
                .url(url)
                .put(requestBody);
        
        // 添加请求头
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        
        Request request = builder.build();
        return executeRequest(request);
    }
    
    /**
     * PUT 请求 (byte[] body)
     */
    public static HttpResponse doPut(String host, String path, String method,
                                     Map<String, String> headers,
                                     Map<String, String> querys,
                                     byte[] body) throws Exception {
        String url = buildUrl(host, path, querys);
        
        RequestBody requestBody = RequestBody.create(body, JSON);
        
        Request.Builder builder = new Request.Builder()
                .url(url)
                .put(requestBody);
        
        // 添加请求头
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        
        Request request = builder.build();
        return executeRequest(request);
    }
    
    /**
     * DELETE 请求
     */
    public static HttpResponse doDelete(String host, String path, String method,
                                        Map<String, String> headers,
                                        Map<String, String> querys) throws Exception {
        String url = buildUrl(host, path, querys);
        
        Request.Builder builder = new Request.Builder()
                .url(url)
                .delete();
        
        // 添加请求头
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        
        Request request = builder.build();
        return executeRequest(request);
    }
    
    /**
     * 构建完整URL
     */
    private static String buildUrl(String host, String path, Map<String, String> querys) 
            throws UnsupportedEncodingException {
        StringBuilder url = new StringBuilder();
        url.append(host);
        
        if (path != null && !path.isEmpty()) {
            if (!path.startsWith("/")) {
                url.append("/");
            }
            url.append(path);
        }
        
        if (querys != null && !querys.isEmpty()) {
            url.append("?");
            boolean first = true;
            for (Map.Entry<String, String> entry : querys.entrySet()) {
                if (!first) {
                    url.append("&");
                }
                url.append(entry.getKey())
                   .append("=")
                   .append(URLEncoder.encode(entry.getValue(), "UTF-8"));
                first = false;
            }
        }
        
        return url.toString();
    }
    
    /**
     * 执行请求
     */
    private static HttpResponse executeRequest(Request request) throws IOException {
        Response response = getClient().newCall(request).execute();
        return new HttpResponse(response);
    }
    
    /**
     * HttpResponse 包装类 - 兼容原 Apache HttpClient 的 HttpResponse
     */
    public static class HttpResponse {
        private final Response response;
        
        public HttpResponse(Response response) {
            this.response = response;
        }
        
        public int getStatusCode() {
            return response.code();
        }
        
        public String getStatusPhrase() {
            return response.message();
        }
        
        public String getStringBody() throws IOException {
            if (response.body() != null) {
                return response.body().string();
            }
            return null;
        }
        
        public byte[] getByteBody() throws IOException {
            if (response.body() != null) {
                return response.body().bytes();
            }
            return null;
        }
        
        public Map<String, List<String>> getHeaders() {
            return response.headers().toMultimap();
        }
        
        public String getHeader(String name) {
            return response.header(name);
        }
        
        public Response getOriginalResponse() {
            return response;
        }
        
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("HTTP/1.1 ").append(response.code()).append(" ").append(response.message()).append("\n");
            sb.append(response.headers());
            try {
                if (response.body() != null) {
                    sb.append("\n").append(response.body().string());
                }
            } catch (IOException e) {
                sb.append("\n[Error reading body: ").append(e.getMessage()).append("]");
            }
            return sb.toString();
        }
    }
}
